package com.itheima;

import java.util.*;
import java.util.function.Predicate;
//概念说明
/*
集合体系：
    集合中的泛型，如果省略，默认是Object数据类型
集合的体系结构
    Collection--单列集合顶层接口
        List--接口，元素可重复，有索引，有序（存和取的顺序保持一致）
            ArrayList--数组实现的列表
            LinkList--链表实现的列表
        Set-接口，元素唯一，无索引
            HashSet--哈希表实现的Set集合
            TreeSet--红黑树实现的Set集合

    Map--双列集合的顶层接口（键对应着值）
            HashMap
            TreeMap

Collection的成员方法
    boolean add(E e)
        --添加到集合
    void clear
        --清空集合
    boolean contains(Object o)
        --判断该元素是否在集合中存在，使用参数o与集合中的元素惊醒equals比较，如果返回true，证明存在
    boolean isEmpty（）
    --判断是否为空
    boolean remove(Object o)
    --删除参数o在结合中的第一个匹配，使用参数o与集合中的元素惊醒equals比较，如果返回true，删除o
    int size（）
    --返回集合长度，元素个数
    defualt boolean removeIf(Predicate?super E>filter)
    --根据条件，删除集合中所有满足条件的元素

List分支特有功能
    void add​(int index,E element)
        --将指定的元素插入此列表中的指定位置（可选操作）。
        将当前位于该位置的元素（如果有）和任何后续元素（向其索引添加一个）移动。
    E remove​(int index)
        --删除该列表中指定位置的元素（可选操作）。
        将任何后续元素移动到左侧（从其索引中减去一个元素）。
        返回从列表中删除的元素。
    E set​(int index,E element)
        用指定的元素（可选操作）替换此列表中指定位置的元素。
    E get​(int index)
        返回此列表中指定位置的元素。

数据结构
    栈
        Last In First Out--LIFO---后进先出
    队列
        FIFO--先进先出
    数组
        存储多个同种数据类型元素的容器
        在内存中是一段连续的空间，每一个元素都有索引，
        可以方便的通过索引获取到每一个元素。查询较快
        数组长度固定，增删元素效率较低
    链表
         非连续的空间，每一个结点都通过记录下一个结点的地址值组成一个链条
         结点：
            --数据域
            --指针域（指向下一个元素的地址值）
         增删只会影响该结点相邻的两个元素，效率高
         查询从头结点或尾结点逐个查询，效率低

    ArrayList--底层结构是数组
       1、ArrayList的空参构造。底层创建了一个空数组
       2、当第一次添加元素，创建了一个默认容量为10 的数组
       3、当数组存满是，扩容，扩容到原来的1.5倍
    LinkedList--底层结构是链表
       在头尾操作元素
*/
public class Demo_Collection {
    public static void main(String[] args) {
//        Collection<String> collection = new ArrayList<>();
//        collection.add("aaa");
//        collection.add("bbb");
//        collection.add("ccc");
//        collection.add("ddd");
//        collection.add("abcd");
//        collection.add("dcba");
        //删除：removeIf
            //调用PredicateImpl类
                /*PredicateImpl p = new PredicateImpl();
                    collection.removeIf(p);*/
            //Lambda表达式
                /*collection.removeIf(new Predicate<String>() {
                    @Override
                    public boolean test(String s) {
                    return s.length() == 3;
                    }
                   });*/
                /*collection.removeIf((String s)->{return s.length()==3;});*/
                /*collection.removeIf(s -> s.length() == 3);3*/

        //迭代器的基本使用Iterator<String> it = collection.iterator();
            //遍历
                /*//获取迭代器
                    Iterator<String> it = collection.iterator();
                    //判断是否有下一个元素
                    while (it.hasNext()){
                        //获取下一个元素
                        String s = it.next();//next方法在循环中只能被调用一次
                        System.out.println(s);
                        }*/
            //删除
//        ArrayList<String> list = new ArrayList<>();
//        list.add("a");
//        list.add("b");
//        list.add("b");
//        list.add("c");
//        list.add("b");
                //基础删除方法
                    /*for (int i = 0; i < list.size(); i++) {
                        String s = list.get(i);
                        if("b".equals(s)){
                            list.remove(s);
                            i--;
                        }
                      }*/
                //迭代器
                    /*Iterator<String> it = list.iterator();
                        while(it.hasNext()){
                            String s = it.next();
                            if(s.equals("b")){
                            //迭代器的删除功能，删除的就是当前正在指向的元素
                                it.remove();;
                             }
                        }*/
                //Lambda表达式:list.removeIf(s->"b".equals(s));
                //并发修改异常
                    /*Iterator<String> it = list.iterator();
                        while(it.hasNext()){
                            String s = it.next();
                            if("b".equals(s)){
                                //ConcurrentModificationException 并发修改异常
                                list.remove("b");
                                //只要删除成功就重新获取迭代器--不建议：如果是增，陷入死循环
                                it = list.iterator();
                            }
                        }
                        System.out.println(list);
                        迭代器遍历集合，集合本身长度发生变化，而迭代器没有重新获取，这样的修改就叫并发修改
                        解决问题：
                            使用迭代器遍历，用迭代器删除
                            建议使用removeIf
                        开发中：极少会在遍历集合的同时增删元素   */

        //增强for ：for(元素的数据类型 变量名：数组或集合对象){}
            //只有实现了Iterable接口的类才能用此遍历
            //变量名 就依次代表集合或数组中的每一个元素，直接使用这个变量即可
            /*ArrayList<String> list = new ArrayList<>();
              list.add("a");
              list.add("b");
              list.add("c");
              list.add("d");
              list.add("e");
              for(String s : list){
                    System.out.println(s);
              }
              System.out.println("------------------");
              int[] arr = {1,2,3,4};
              for (int i : arr) {
                    System.out.println(i);
              }*/

        //练习集合
        //根据不同数据选择不同的集合
//        ArrayList<Student> list = new ArrayList<>();
//        //准备数据添加到集合中
//        list.add(new Student("关",30));
//        list.add(new Student("张",28));
//        list.add(new Student("赵",32));
//        list.add(new Student("马",29));
//        list.add(new Student("黄",42));
        //不同遍历--迭代器、增强for
            /*Iterator<Student> it = list.iterator();
                while (it.hasNext()){
                    Student stu = it.next();
                    System.out.println(stu);
                }
                System.out.println("----------------");
                for (Student student : list) {
                    System.out.println(student);
                }*/

        //
        /*LinkedList<String> list = new LinkedList<>();
        list.addFirst("aaa");
        list.addFirst("bbb");
        list.addFirst("ccc");

        System.out.println(list);*/
        //遍历
        /*for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
        System.out.println("----------------------------");
        //迭代器
        Iterator<String> it = list.iterator();
        while (it.hasNext()){
            String s = it.next();
            System.out.println(s);
        }
        System.out.println("----------------------------");
        //增强for
        for (String s : list) {
            System.out.println(s);
        }*/
        //水浒卡，从上到下放好，扔一张，下一张放最后，一直到剩最后一张
        LinkedList<Integer> list = new LinkedList<>();
        for (int i = 1; i <=108 ; i++) {
            list.add(i);
        }
        while (list.size()>1){
            list.removeFirst();
            list.add(list.removeFirst());
        }
        System.out.println(list.get(0));
    }
}
//PredicateImp类implements Predicate<String>，重写
/*
class PredicateImpl implements Predicate<String> {
    @Override
    public boolean test(String s) {
        return s.length() == 3;
    }
}*/

//学生类：重写toString()...equals()方法
/*class Student{
    private  String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Student student = (Student) o;

        if (age != student.age) return false;
        return name != null ? name.equals(student.name) : student.name == null;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }
}*/
